<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>实例操作</title>
    <style>
        *{
            padding: 0;
            margin: 0;
            box-sizing: content-box;
        }
        body{
            padding: 30px;
        }
        .slide{
            width: 300px;
            display: flex;
            flex-direction: column;
        }
        .slide dt{
            height: 30px;
            background: #34495e;
            color: wheat;
            display: flex;
            align-items: center;
            padding-left: 10px;
            cursor: pointer;
        }
        .slide dt:first-of-type{
            border-top-left-radius: 10px;
            border-top-right-radius: 10px;
        }
        .slide dd{
            height: 100px;
            background: #f1c40f;
            overflow: hidden;
        }
        .slide dd div{
            padding: 10px;
        }
        .slide dd:last-of-type{
            border-bottom-left-radius: 10px;
            border-bottom-right-radius: 10px;
        }
    </style>
</head>
<body>
    <div class="slide s1">
        <dt>后盾人</dt>
        <dd>
            <div>houdunren.com</div>
        </dd>
        <dt>后盾人</dt>
        <dd>
            <div>hdcms.com</div>
        </dd>
        <dt>后盾人</dt>
        <dd>
            <div>hscmssss.com</div>
        </dd>
    </div>
</body>
</html>

<script>

    //动画类编写完毕，当然可以继续给里面添加需要的方法
    //动画的类 是一个单独的类   跟其他的并没有其他的牵扯
    class Animation{
        constructor(el){
            this.el = el;
            this.defaultHeight = this.height;
            this.isShow = true;
            this.timeOut = 1;
        }

        //元素的隐藏
        hide(callback){
            this.isShow = false;
            let id = setInterval(() => {
                if(this.height <= 0){
                    clearInterval(id);
                    callback && callback();
                    return;
                }
                this.height = this.height - 1;
            },this.timeOut);
        }

        //元素的显示
        show(callback){
            this.isShow = true;
            let id = setInterval(() => {
                if(this.height >= this.defaultHeight){
                    clearInterval(id);
                    callback && callback();
                    return;
                }
                this.height = this.height + 1;
            },this.timeOut);
        }

        //计算元素的高度
        get height(){
            return window.getComputedStyle(this.el).height.slice(0,-2)*1;
        }

        //设置元素的高度
        set height(value){
            this.el.style.height = value + 'px';
        }
    }


    //编写面板类，控制面板的元素
    class Slide{
        constructor(el){
            //获取当前的面板
            this.el = document.querySelector(el);

            //获取面板下面的所有的dt
            this.links = this.el.querySelectorAll('dt');

            //获取面板下面所有的dd
            //初始化的时候将所有的dd都变为可操作的面板
            this.panels = [...this.el.querySelectorAll('dd')].map(item => {
                return new Panel(item);
            });

            //绑定事件
            this.bind();
        }

        bind(){
            this.links.forEach((elem,i) => {
                elem.addEventListener('click',() => {
                   //点击之后调用方法
                   //将当前的打开，将其他所有的关闭
                   this.action(i);
                });
            });
        }

        action(i){
            //点击的时候，将除了当前点击的元素进行显示，其他的都进行隐藏操作
            Panel.hideAll(Panel.filter(this.panels,i),() => {
                this.panels[i].show();
            });
        }
    }


    //声明面板类
    //直接使用类名调用的是静态方法
    class Panel extends Animation{
        static num = 0;
        static hideAll(items,callback){
            //动画没有执行完毕的时候，不做其他的事情
            if(Panel.num > 0) return false;
            items.forEach(item => {
                Panel.num++;
                item.hide(() => {
                    Panel.num-- ;
                });
            });
            callback && callback();
        }

        static filter(items,i){
            return items.filter((item,index) => index != i);
        }
    }

    new Slide('.s1');
</script>